package com.ayf.payment.game.api.controller;

import cn.hutool.core.lang.Validator;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.dto.*;
import com.ayf.payment.game.api.dto.criteria.OrderCriteria;
import com.ayf.payment.game.api.dto.criteria.OrderInfoCriteria;
import com.ayf.payment.game.api.dto.criteria.PartitionStatisticsCriteria;
import com.ayf.payment.game.api.dto.getaway.GameRechargeGetWayDTO;
import com.ayf.payment.game.api.dto.platform.SettleConfigDTO;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.service.GameInfoService;
import com.ayf.payment.game.api.service.MerchantConfigService;
import com.ayf.payment.game.api.service.OrderService;
import com.ayf.payment.game.api.service.OrderSplitService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.CommonResult;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.IPUtils;
import com.ayf.payment.game.api.utils.QRCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @Description: 订单控制层
 * @Author: zh-liang
 * @Date : 2019-12-18 11:58
 */
@RestController
@RequestMapping("/v/order")
public class OrderController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private GameInfoService gameInfoService;
    @Autowired
    RedisCacheUtil redisCacheUtil;

    @Autowired
    private MerchantConfigService merchantConfigService;
    @Autowired
    private OrderSplitService splitService;

    private static String RECHARGE_NUBER_REG="^[A-Za-z0-9]+$";

    /**
     * 订单详情
     *
     * @param criteria
     * @return
     */
    @PostMapping("/details")
    public CommonResult<GameRechargeGetWayDTO> orderDetails(@RequestBody OrderCriteria criteria) {
        if (criteria == null) {
            throw new ParameterException("参数不能为空");
        }
        if (criteria.getPayCode() == null) {
            throw new ParameterException("支付方式不能为空");
        }
        if (criteria.getPartitionId() == null) {
            throw new ParameterException("分区不能为空");
        }
        if (criteria.getAmount() == null) {
            throw new ParameterException("充值金额不能为空");
        }
        if (StringUtils.isBlank(criteria.getRechargeNumber())) {
            throw new ParameterException("充值账号不能为空");
        }
        GameRechargeGetWayDTO gameRechargeDTO = orderService.getOrderDetails(criteria);

        return new CommonResult<GameRechargeGetWayDTO>(CommonConstants.RETURN_SUCCESS, CommonConstants.OPERATION_SUCCESS, gameRechargeDTO);
    }

    /**
     * 点击充值，创建订单
     *
     * @param criteria
     * @return
     */
    @PostMapping("/add")
    public CommonResult<Map<String, Object>> add(@RequestBody OrderCriteria criteria, HttpServletRequest request) throws Exception {
        if (criteria == null) {
            throw new ParameterException("参数不能为空");
        }
        if (StringUtils.isBlank(criteria.getPayCode())) {
            throw new ParameterException("支付方式不能为空");
        }
        if (StringUtils.isBlank(criteria.getRechargeNumber())) {
            throw new ParameterException("充值账号不能为空");
        }
        if (!Pattern.matches(RECHARGE_NUBER_REG,criteria.getRechargeNumber())){
            throw new ParameterException("充值账号格式错误");
        }
        if (StringUtils.isBlank(criteria.getRechargeNumberRepeat())) {
            throw new ParameterException("确认账号不能为空");
        }
        if (!Pattern.matches(RECHARGE_NUBER_REG,criteria.getRechargeNumberRepeat())){
            throw new ParameterException("确认账号格式错误");
        }
        if (!StringUtils.equals(criteria.getRechargeNumber(), criteria.getRechargeNumberRepeat())) {
            throw new ParameterException("充值与确认账号数值不一致");
        }
        if (criteria.getAmount() == null) {
            throw new ParameterException("充值金额不能为空");
        }
        if (criteria.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new ParameterException("充值金额必须大于0元");
        }
        if (StringUtils.isNotEmpty(criteria.getPhone()) && !Validator.isMobile(criteria.getPhone())) {
            throw new ParameterException("手机号格式错误");
        }
        SettleConfigDTO settleConfigDTO = merchantConfigService.selectConfigByPartitionId(criteria.getPartitionId());
        if (settleConfigDTO != null) {
            BigDecimal rechargeMinAmt = new BigDecimal(settleConfigDTO.getMinRechargeAmount());
            BigDecimal rechargeMaxAmt = new BigDecimal(settleConfigDTO.getMaxRechargeAmount());
            if (criteria.getAmount().compareTo(rechargeMinAmt) < 0) {
                throw new ParameterException("充值金额不能小于最低充值金额[" + rechargeMinAmt + "]元");
            }
            if (rechargeMaxAmt.compareTo(criteria.getAmount()) < 0) {
                throw new ParameterException("充值金额不能大于最大充值金额[" + rechargeMaxAmt + "]元");
            }
        }
        String clientIp = IPUtils.getIp(request);
        criteria.setClientIp(clientIp);
        Map<String, Object> result = orderService.insertOrder(criteria);
        return new CommonResult<Map<String, Object>>(CommonConstants.RETURN_SUCCESS, "下单成功", result);
    }

    /**
     * 查询订单是否充值成功
     *
     * @param order
     * @return
     */
    @PostMapping("/selectStatus")
    public CommonResult<OrderDTO> selectStatus(@RequestBody OrderDTO order) {
        if (order == null || StringUtils.isBlank(order.getMerchantOrderNo())) {
            throw new ParameterException("订单号不能为空");
        }
        OrderDTO dto = orderService.selectOrderByOrderNo(order.getMerchantOrderNo());
        if (dto == null) {
            throw new NullSetException("订单号输入错误");
        }
        return new CommonResult<>(CommonConstants.RETURN_ERROR, "查询成功", dto);
    }

    /**
     * 商户查询订单信息集合
     *
     * @param merchantDTO
     * @param orderCriteria
     * @return
     */
    @PostMapping("/list")
    public CommonResult<ChargeOrderResponseDTO> selectOrder(MerchantDTO merchantDTO,
                                                            @RequestBody OrderInfoCriteria orderCriteria) {
        orderCriteria.setMerchantId(merchantDTO.getId());
        ChargeOrderResponseDTO dto = orderService.selectOrderList(orderCriteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功", dto);
    }

    /**
     * 今日订单查询
     *
     * @param merchantDTO
     * @return
     */
    @PostMapping("/todayList")
    public CommonResult<PageDTO> selectTodayOrder(MerchantDTO merchantDTO, @RequestBody OrderInfoCriteria orderCriteria) {
        orderCriteria.setMerchantId(merchantDTO.getId());
        Date date = new Date();
        orderCriteria.setStartTime(DateUtils.dateToString(date, "yyyy-MM-dd 00:00:00"));
        orderCriteria.setEndTime(DateUtils.dateToString(date, "yyyy-MM-dd HH:mm:ss"));
        orderCriteria.setOrderStatus(OrderStatus.SUCCESS);
        orderCriteria.setCorrectStatus(0);
        PageHelper.startPage(orderCriteria.getPageNum(), orderCriteria.getPageSize());
        List<OrderInfoDTO> orderList = orderService.todayLastOrderList(orderCriteria);
        PageInfo<OrderInfoDTO> pageInfo = new PageInfo<>(orderList);
        PageDTO dto = BeanConvertUtils.convert(pageInfo, PageDTO.class);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功", dto);
    }

    /**
     * 获取支付二维码
     *
     * @param request
     * @param response
     */
    @GetMapping("/getPayQrImage")
    public void getPayQrImage(HttpServletRequest request, HttpServletResponse response) {
        String merchantOrderNo = request.getParameter("merchantOrderNo");
        if (StringUtils.isNotEmpty(merchantOrderNo)) {
            String payUrl = redisCacheUtil.getObjectFromCache(merchantOrderNo);
            if (StringUtils.isNotEmpty(payUrl)) {
                try {
                    QRCode.createQrCode(response.getOutputStream(), payUrl, "gif");
                } catch (Exception e) {
                    LogPortal.error("商户订单号[{}]获取支付二维码发生{}异常", e, merchantOrderNo, e.getClass().getName());
                }
            }
        }
    }

    @GetMapping("/getPayParam")
    public CommonResult<?> getPayParam(HttpServletRequest request) {
        String merchantOrderNo = request.getParameter("merchantOrderNo");
        if (StringUtils.isNotEmpty(merchantOrderNo)) {
            Map map = redisCacheUtil.getObjectFromCache("PayBean_".concat(merchantOrderNo));
            if (map != null){
                return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功", map);
            }else {
                return new CommonResult<>(CommonConstants.RETURN_ERROR, "支付参数已过期，请重新下单",null);
            }
        }else {
            return new CommonResult<>(CommonConstants.RETURN_ERROR, "支付订单号不存在，请重新下单",null);
        }
    }

    /**
     * 分区统计查询
     *
     * @param merchantDTO
     * @param criteria
     * @return
     */
    @PostMapping("/partitionStatisticsList")
    public CommonResult<List<PartitionStatisticsDTO>> partitionStatisticsList(MerchantDTO merchantDTO, @RequestBody PartitionStatisticsCriteria criteria) {
        if (criteria == null) {
            throw new ParameterException("参数不能为空");
        }
        criteria.setMerchantId(merchantDTO.getId());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, CommonConstants.OPERATION_SUCCESS, orderService.selectPartitionChargeSuccessDetailList(criteria));
    }

    @PostMapping("/retryOrders")
    public CommonResult retryOrders(MerchantDTO merchantDTO, @RequestBody OrderCriteria criteria) {
        if (criteria == null) {
            throw new ParameterException("参数不能为空");
        }
        if (null == criteria.getMerchantOrderNos() || 0 == criteria.getMerchantOrderNos().length) {
            throw new ParameterException("请选择订单");
        }
        return  orderService.retryOrders(criteria.getMerchantOrderNos());
    }

    @PostMapping("/checkPayOrder")
    public CommonResult checkPayOrder(@RequestBody OrderCriteria criteria) {
        if (criteria == null) {
            throw new ParameterException("参数不能为空");
        }
        if (null == criteria.getMerchantOrderNo()) {
            throw new ParameterException("请选择订单");
        }

        return  orderService.checkPayOrder(criteria.getMerchantOrderNo());
    }


    /**
     * 充值界面，玩家订单号查询，只查询近3天的订单
     * @param order
     * @return
     */
    @PostMapping("/playerQueryOrderNo")
    public CommonResult<OrderInfoDTO> playerQueryOrderNo(@RequestBody OrderDTO order) {
        if (order == null || StringUtils.isBlank(order.getMerchantOrderNo())) {
            throw new ParameterException("订单号不能为空");
        }
        OrderInfoDTO dto = orderService.playerQueryOrderNo(order.getMerchantOrderNo());
        if (dto == null) {
            throw new NullSetException("订单号输入错误或不在查询时间范围内");
        }
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功", dto);
    }

    /**
     * 获取分账明细记录
     * @param orderId
     * @return
     */
    @PostMapping("/getSplitOrderList/{orderId}")
    public CommonResult<?> getSplitOrderList(@PathVariable("orderId")String orderId) {
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "查询成功",splitService.getOrderSplitsByOrderId(orderId));
    }


}
